# -*- coding: ascii -*-
# vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab
#
# find_enc_notes.py  - find (only) encrypted notes
# Copyright (C) 2009  Chris Clark
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.


"""
Find Enc Notes

Re-encrypt notes with consistent password.

Recursively Search Tombo encrypted notes. 
Tries to decrypt with (entered) password, if it fails prompts for the
password and then once decrypted re-encrypts using the 1st specified password.

Main use is to ensure all encrypted notes use the same password so that global
searches do not require the password to be re-entered for each file.

Usage: %prog [options] args
    -d, --dir_name=PATH: PATH Name Directory of notes to search, if omitted, args is used instead
    -p, --password=PASSWORD: Password to use for all encrypted notes (if omitted will be prompted for password, specifying password at command line can be a security risk as password _may_ be visible in process/task list and/or shell history)
    -t, --time: Print query search time
"""
## FIXME make MANDATORY an option
## FIXME make DIRNAME a "type"

import sys
import time

import optionparse
#import weboptionparse as optionparse

from pytombo.search import recurse_notes, search_iter, SearchCancelled
from pytombo.tombonote import gen_caching_get_password, gen_static_password, remove_leading_path
import pytombo.tombonote as tombonote
import pytombo.chi_io as chi_io



def filter_enc_notes_only(in_filename):
    name = in_filename.lower()
    return name.endswith('.chi')
def example_progess_callback(*args, **kwargs):
    print 'example_progess_callback:', args, kwargs

def gen_new_filename(in_filename):
    return in_filename+'_MOD'


def main(argv=None):
    if argv is None:
        argv = sys.argv

    opt, args = optionparse.parse(__doc__, argv[1:])
    def usage_error(msg=''):
        raise SystemExit(optionparse.optionstring.replace("%prog",sys.argv[0]) + '\n' + msg) ## fixme make this stuff cass based in module, optionstring global is not cool...
    
    path_to_search = opt.dir_name
    if not path_to_search:
        try:
            path_to_search = args[0] ## FIXME TODO glob all args
        except IndexError, info:
            usage_error('ERROR: Missing search path/directory')
    
    if opt.password:
        password_func = gen_static_password(opt.password).gen_func()
    else:
        caching_console_password_prompt = gen_caching_get_password(dirname=path_to_search).gen_func()
        password_func = caching_console_password_prompt
    
    progess_callback=None
    #progess_callback=example_progess_callback
    
    
    password_cipher = password_func()
    temp_password_prompt = gen_caching_get_password(dirname=path_to_search).gen_func()
    if opt.time:
        start_time = time.time()
    for x in recurse_notes(path_to_search, filter_enc_notes_only):
        if progess_callback:
            progess_callback(filename=x)
        try:
            #note_text = tombonote.file_contents(x, password_func, dos_newlines=False)
            note_text = tombonote.decrypt_file_ignore_errors(x, password_cipher)
            #print type(note_text)
            #print note_text
            if note_text:
                print 'OK', x
            else:
                resetflag=False
                while not note_text:
                    print 'FAIL', x
                    temp_password = temp_password_prompt(prompt='need password for %r' %x, reset=resetflag)
                    note_text = tombonote.decrypt_file_ignore_errors(x, temp_password)
                    resetflag=True
                if note_text:
                    print 'FOUND PW for', x
                    newfilename=gen_new_filename(x)
                    print 'creating', newfilename
                    tombonote.encrypt_file(newfilename, note_text, password_cipher, dos_newlines=False)

        except chi_io.BadPassword, info:
            print 'search cancelled because of', repr(info), repr(str(info))

    if opt.time:
        end_time = time.time()
        search_time = end_time - start_time
        print 'Query time: %.2f seconds' % search_time

    return 0


if __name__ == "__main__":
    sys.exit(main())
